package fr.alma.trajectory.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.media.opengl.awt.GLCanvas;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTextPane;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

import fr.alma.trajectory.calculating.ICalculator;
import fr.alma.trajectory.commons.Shape;
import fr.alma.trajectory.commons.SpaceObject;
import fr.alma.trajectory.commons.SpacePoint;
import fr.alma.trajectory.rendering.IViewer;

/**
 * Implementation du composant graphique
 * @author gouzy && ian
 */
public class GUI extends JFrame implements IGUI{

	private static final long serialVersionUID = 1L;
	
	/**n
	 * Composant de rendu visuel
	 */
	private IViewer viewer;
	
	/**
	 * Composant de calcul de la trajectoire
	 */
	private ICalculator calculator;

	/**
	 * Largeur de la fenetre
	 */
	private static final int WIDTH = 800;
	
	/**
	 * Hauteur de la fenetre
	 */
	private static final int HEIGHT = 600;

	/**
	 * Titre de la fenetre
	 */
	private static final String TITLE = "Visualisation d'une trajectoire par balayage";

	/**
	 * Le panel a options
	 */
	private JPanel optionsPanel;
	
	public GUI(IViewer viewer, ICalculator calculator) {
		this.viewer = viewer;
		this.calculator = calculator;
		
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle(TITLE);
		this.setSize(WIDTH, HEIGHT);
		this.getContentPane().setLayout(new BorderLayout(1, 1));
		this.getContentPane().add(getScene() ,BorderLayout.CENTER);
		this.getContentPane().add(getOptions(),BorderLayout.EAST);
	}

	@Override
	public void display(){
		this.setVisible(true);
	}
	
	/**
	 * Recuperer la scene de visualisation
	 * @return La scene
	 */
	private GLCanvas getScene(){
		return viewer.getView2(new ArrayList<SpaceObject>());
	}

	
	
	private List<SpacePoint> trajectoryList = new ArrayList<SpacePoint>();
	
	
	/**
	 * Construire le panel a options s'il n'existe pas encore, le retourner sinon
	 * @return Le panel a options
	 */
	private JPanel getOptions() {
		
		
		
		if(optionsPanel==null){
			optionsPanel = new JPanel();
			optionsPanel.setLayout(new FormLayout(new ColumnSpec[] {
					ColumnSpec.decode("default:grow"),},
					new RowSpec[] {
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC,
					FormFactory.RELATED_GAP_ROWSPEC,
					FormFactory.DEFAULT_ROWSPEC}));
			
			final JComboBox functionsCombo = new JComboBox();
			functionsCombo.setModel(new DefaultComboBoxModel(
										new String[] {"Triangle", "Rectangle", "Carre", "Losange"}));
			
			optionsPanel.add(functionsCombo, "1, 1, fill, default");
			
			JLabel targetLabel = new JLabel("Point d'arrivee");
			optionsPanel.add(targetLabel, "1, 3, fill, fill");
			
	
			
			final JTextField targetField = new JTextField("x y z");
			targetField.addMouseListener(new MouseAdapter() {
				
				@Override
				public void mousePressed(MouseEvent arg0) {
					targetField.setText("");
				}
				
			});
			optionsPanel.add(targetField, "1, 5, fill, default");

			
			final JTextField targetField2 = new JTextField("x y z");
			targetField2.addMouseListener(new MouseAdapter() {
				
				@Override
				public void mousePressed(MouseEvent arg0) {
					targetField2.setText("");
				}
				
			});
			
			
			final JTextPane LabelPoints = new JTextPane();
			LabelPoints.setEditable(false);

			
			
			JLabel targetLabelIntermediaire = new JLabel("Point intermédiaire");
			optionsPanel.add(targetLabelIntermediaire, "1, 7, fill, fill");

			// bouton AJOUTER
			JButton addButton = new JButton("Ajouter");
			addButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					double[] targetCoord2 = getTarget(targetField2.getText());
					if(targetCoord2 == null) {
						message("Coordonnees incorrectes", JOptionPane.ERROR_MESSAGE);
						return;
					}
					SpacePoint step = new SpacePoint(targetCoord2[0], targetCoord2[1], targetCoord2[2]);
					trajectoryList.add(step);
				
					LabelPoints.setText(LabelPoints.getText()+"< "+targetCoord2[0]+" , "+targetCoord2[1]+" , "+targetCoord2[2]+" >\n");
					//StringBuilder help = new StringBuilder();

				}
				
			});
			
			optionsPanel.add(targetField2, "1, 9, fill, default");
			optionsPanel.add(addButton, "1,11, fill, fill");
			
			
			// bouton CALCULER
			JButton calculButton = new JButton("Calculer");
			calculButton.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					Controller controller = new Controller(viewer, calculator);
					double[] targetCoord = getTarget(targetField.getText());
					if(targetCoord == null) {
						message("Arrivee de l'objet incorrecte", JOptionPane.ERROR_MESSAGE);
						return;
					}
					int shapeIndex = functionsCombo.getSelectedIndex();
					SpacePoint target = new SpacePoint(targetCoord[0], targetCoord[1], targetCoord[2]);
					trajectoryList.add(target); 
					
					//System.out.println(trajectoryList);
					controller.run(getShape(shapeIndex), trajectoryList);
					trajectoryList.clear();
				}
				
			});
			
			optionsPanel.add(calculButton, "1, 17, fill, default");
			
			JLabel targetLabel3 = new JLabel("Liste des points entrés");
			optionsPanel.add(targetLabel3, "1, 13, fill, fill");
			
			optionsPanel.add(LabelPoints, "1, 15, fill, fill");
			
			
		}
		return optionsPanel;
	}
	
	public void message(String text, int type) {
		JOptionPane.showMessageDialog(this, text, "Message", type);
	}
	
	private double[] getTarget(String text){
		String[] splitSpace = text.split(" ");
		if(splitSpace == null || splitSpace.length != 3) {
			return null;
		}
		try {
			double d1 = Double.parseDouble(splitSpace[0]),
					d2 = Double.parseDouble(splitSpace[1]),
					d3 = Double.parseDouble(splitSpace[2]);
			return new double[] {d1, d2, d3};
		} catch(NumberFormatException nfe) {
			return null;
		}
	}
	
	private Shape getShape(int index){
		switch(index){
		case 0 :
			return Shape.Triangle;
		case 1 :
			return Shape.Rectangle;
		case 2 :
			return Shape.Square;
		case 3 :
			return Shape.Losange;
		}
		return null;
	}

	
}
